/* eslint-disable */
// @ts-check

/** 非法字符 */
const InvalidCharRegex = /[^\u0000-\u00ff]/;

/** 不支持的 format 类型 */
const UnsupportedFormats = [
  /** data-time: 后端格式不符合规范 */
  'date-time',
  /** int64: 超出 js number 长度 */
  'int64',
  /** float */
  'float',
  /** double */
  'double',
];

/**
 * 验证字符串
 * @param {string} s
 */
const validateString = (s) => {
  if (!s.length) {
    throw new Error('为空字符串');
  }

  if (InvalidCharRegex.test(s)) {
    throw new Error('包含中文');
  }
};

/**
 * 验证 schema
 * @param {Record<string, any>} schema
 * @param {readonly string[]} paths
 */
const validateSchema = (schema, paths) => {
  if (!schema) return;
  for (const [key, value] of Object.entries(schema)) {
    const currentPaths = [...paths, key];

    try {
      // key 不能是中文
      validateString(key);

      // title 的值不能是中文
      if (key === 'title' && typeof value === 'string') {
        validateString(value);
      }
    } catch (err) {
      throw new Error(
        `swagger json 验证错误 at ${[...paths, key].join('.')}: ${err.message}`,
      );
    }

    // 对于不支持的 format 类型，直接去掉
    if (key === 'format' && UnsupportedFormats.includes(value)) {
      delete schema[key];
    }

    // 去除schema的schema标记
    if (key === '$schema') {
      delete schema[key];
    }

    // 递归
    // console.log(typeof value);
    if (typeof value === 'object') {
      validateSchema(value, currentPaths);
    }
  }
};

/**
 * 验证 swagger json 是否有中文
 * @param {import("auto-service/lib/consts").SwaggerJson} swagger
 */
module.exports = (swagger) => {
  // paths
  if (swagger.paths) {
    for (const [pathName, pathData] of Object.entries(swagger.paths)) {
      for (const [methodName, methodData] of Object.entries(pathData)) {
        const { parameters, responses } = methodData;

        // 请求
        if (parameters) {
          for (const parameterData of parameters) {
            validateSchema(parameterData, [
              'paths',
              pathName,
              methodName,
              'parameters',
              parameterData.name,
            ]);
          }
        }

        // 响应
        for (const [status, responsesData] of Object.entries(responses)) {
          validateSchema(responsesData, [
            'paths',
            pathName,
            methodName,
            'responses',
            status,
          ]);
        }
      }
    }
  }

  // definitions
  if (swagger.definitions) {
    validateSchema(swagger.definitions, ['definitions']);
  }
};
